Matrix Functions

A Matrix object represents a 3 ×3 matrix that, in turn, represents an affine transformation. A Matrix object stores only six of the 9 numbers in a 3 ×3 matrix because all 3 ×3 matrices that represent affine transformations have the same third column (0, 0, 1).

Name Description
GdipCloneMatrix Creates a new Matrix object that is a copy of a Matrix object.
GdipCreateMatrix Creates and initializes a Matrix object that represents the identity matrix.
GdipCreateMatrix2 Creates and initializes a Matrix object based on six numbers that define an affine transformation.
GdipCreateMatrix3 Creates a Matrix object based on a rectangle and a point.
GdipCreateMatrix3I Creates a Matrix object based on a rectangle and a point.
GdipDeleteMatrix Deletes the specified Matrix object.
GdipGetMatrixElements Gets the elements of a matrix. The elements are placed in an array in the order m11, m12, m21, m22, m31, m32, where mij denotes the element in row i, column j.
GdipInvertMatrix If the matrix is invertible, this function replaces its elements with the elements of its inverse.
GdipIsMatrixEqual Determines whether the elements of a matrix are equal to the elements of another matrix.
GdipIsMatrixIdentity Determines whether the matrix is the identity matrix.
GdipIsMatrixInvertible Determines whether the matrix is invertible.
GdipMultiplyMatrix Updates a matrix with the product of itself and another matrix.
GdipRotateMatrix Updates a matrix with the product of itself and a rotation matrix.
GdipScaleMatrix Updates a matrix with the product of itself and a scaling matrix.
GdipSetMatrixElements Sets the elements of a matrix.
GdipShearMatrix Updates a matrix with the product of itself and a shearing matrix.
GdipTransformMatrixPoints Multiplies each point in an array by a matrix. Each point is treated as a row matrix. The multiplication is performed with the row matrix on the left and a matrix on the right.
GdipTransformMatrixPointsI Multiplies each point in an array by a matrix. Each point is treated as a row matrix. The multiplication is performed with the row matrix on the left and a matrix on the right.
GdipTranslateMatrix Updates a matrix with the product of itself and a translation matrix.
GdipVectorTransformMatrixPoints Multiplies each vector in an array by a matrix. The translation elements of a matrix (third row) are ignored. Each vector is treated as a row matrix. The multiplication is performed with the row matrix on the left and a matrix on the right.
GdipVectorTransformMatrixPointsI Multiplies each vector in an array by a matrix. The translation elements of a matrix (third row) are ignored. Each vector is treated as a row matrix. The multiplication is performed with the row matrix on the left and a matrix on the right.

GdipCloneMatrix

Creates a new Matrix object that is a copy of a Matrix object.

FUNCTION GdipCloneMatrix (BYVAL matrix AS GpMatrix PTR, BYVAL cloneMatrix AS GpMatrix PTR PTR) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
cloneMatrix [out] Pointer to a variable that receives a pointer to the new Matrix object.

Example

' ========================================================================================
' This example demonstrates matrix cloning and transformation using the GDI+ Flat API.
' It draws two rectangles: one scaled horizontally, and one scaled and translated.
' Note: DPI-Aware Composite Transform Strategy Apply logical transforms via matrix, then
' prepend DPI scaling via GdipScaleWorldTransform. Use UnitPixel for pens to maintain
' consistent stroke width.
' ========================================================================================
SUB Example_CloneMatrix (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96

   ' // Create a matrix for horizontal scaling
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix2(3, 0, 0, 1, 0, 0, @matrix)

   ' // Clone the matrix
   DIM clonedMatrix AS GpMatrix PTR
   hStatus = GdipCloneMatrix(matrix, @clonedMatrix)

   ' // Apply translation to the cloned matrix
   hStatus = GdipTranslateMatrix(clonedMatrix, 40 * rxRatio, 25 * ryRatio, MatrixOrderAppend)

   ' // Create a blue pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLUE, 1 * rxRatio, UnitPixel, @pen)

   ' // Apply first transform and draw scaled rectangle
   hStatus = GdipSetWorldTransform(graphics, matrix)
   hStatus = GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawRectangle(graphics, pen, 0, 0, 100, 100)

   ' // Apply second transform and draw scaled + translated rectangle
   hStatus = GdipSetWorldTransform(graphics, clonedMatrix)
   hStatus = GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawRectangle(graphics, pen, 0, 0, 100, 100)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF clonedMatrix THEN GdipDeleteMatrix(clonedMatrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipCreateMatrix

Creates and initializes a Matrix object that represents the identity matrix.

FUNCTION GdipCreateMatrix (BYVAL matrix AS GpMatrix PTR PTR) AS GpStatus
Parameter Description
matrix [out] Pointer to a variable that receives a pointer to the new created Matrix object.

Usage example

DIM matrix AS GpMatrix PTR
GdipCreateMatrix(@matrix)

GdipCreateMatrix2

Creates and initializes a Matrix object based on six numbers that define an affine transformation.

FUNCTION GdipCreateMatrix2 (BYVAL m11 AS REAL, BYVAL m12 AS REAL, BYVAL m21 AS REAL, BYVAL m22 AS REAL, _
         BYVAL dx AS REAL, BYVAL dy AS REAL, BYVAL matrix AS GpMatrix PTR PTR) AS GpStatus
Parameter Description
m11 [in] Simple precision value that specifies the element in the first row, first column.
m12 [in] Simple precision value that specifies the element in the first row, second column.
m21 [in] Simple precision value that specifies the element in the second row, first column.
m22 [in] Simple precision value that specifies the element in the second row, second column.
dx [in] Simple precision value that specifies the element in the third row, first column.
dy [in] Simple precision value that specifies the element in the third row, second column.
matrix [out] Pointer to a variable that receives a pointer to the new created Matrix object.

Usage example

DIM matrix AS GpMatrix PTR
GdipCreateMatrix2(3, 0, 0, 1, 0, 0, @matrix)

GdipCreateMatrix3

Creates a Matrix object based on a rectangle and a point.

FUNCTION GdipCreateMatrix3 (BYVAL rect AS CONST GpRectF PTR, BYVAL dstplg AS CONST GpPointF PTR, _
   BYVAL matrix AS GpMatrix PTR PTR) AS GpStatus
FUNCTION GdipCreateMatrix3I (BYVAL rect AS CONST GpRect PTR, BYVAL dstplg AS CONST GpPoint PTR, _
   BYVAL matrix AS GpMatrix PTR PTR) AS GpStatus
Parameter Description
rect [in] Reference to a GpRect structure. The x data member of the rectangle specifies the matrix element in row 1, column 1. The y data member of the rectangle specifies the matrix element in row 1, column 2. The width data member of the rectangle specifies the matrix element in row 2, column 1. The height data member of the rectangle specifies the matrix element in row 2, column 2.
dstplg [in] Pointer to a GpPoint structure. The x data member of the point specifies the matrix element in row 3, column 1. The y data member of the point specifies the matrix element in row 3, column 2.
matrix [out] Pointer to a variable that receives a pointer to the new created Matrix object.

Example

' ========================================================================================
' Creates a transformation matrix based on a source rectangle and a destination parallelogram.
' This is especially useful for mapping one shape onto another—like skewing, rotating, or
' stretching a rectangle into a custom shape.
' ========================================================================================
SUB Example_CreateMatrix3 (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   DIM ryRatio AS SINGLE = dpiY / 96

   ' // Define source rectangle
   DIM srcRect AS GpRectF = (0, 0, 100, 60)

   ' // Define destination parallelogram points
   DIM destPoints(0 TO 2) AS GpPointF
   destPoints(0).x = 50  : destPoints(0).y = 50      ' Top-left
   destPoints(1).x = 160 : destPoints(1).y = 40      ' Top-right
   destPoints(2).x = 60  : destPoints(2).y = 120     ' Bottom-left

   ' // Create matrix to map srcRect to dstPoints
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix3(@srcRect, @destPoints(0), @matrix)

   ' // Apply matrix to graphics
   hStatus = GdipSetWorldTransform(graphics, matrix)

   ' // Create pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_RED, 2 * rxRatio, UnitPixel, @pen)

   ' // Draw transformed rectangle
   GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawRectangle(graphics, pen, 0, 0, 100, 60)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipDeleteMatrix

Deletes the specified Matrix object.

FUNCTION GdipDeleteMatrix (BYVAL matrix AS GpMatrix PTR) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.

Usage example

DIM matrix AS GpMatrix PTR
hStatus = GdipCreateMatrix2(3, 0, 0, 1, 0, 0, @matrix)
...
...
...
IF matrix THEN GdipDeleteMatrix(matrix)

GdipGetMatrixElements

Gets the elements of a matrix. The elements are placed in an array in the order m11, m12, m21, m22, m31, m32, where mij denotes the element in row i, column j.

FUNCTION GdipGetMatrixElements (BYVAL matrix AS CONST GpMatrix PTR, BYVAL matrixOut AS REAL PTR) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
matrixOut [out] Pointer to an array that receives the matrix elements. The size of the array should be 6 x SIZEOF(SINGLE), i.e. 24.

Example

' ========================================================================================
' Retrieves the six elements of a transformation matrix. This is useful for inspecting or
' debugging the current transformation state.
' ========================================================================================
SUB Example_GetMatrixElements (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   DIM ryRatio AS SINGLE = dpiY / 96
   GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)

   ' // Create identity matrix
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix(@matrix)

   ' // First translate
   hStatus = GdipTranslateMatrix(matrix, 40 * rxRatio, 30 * ryRatio, MatrixOrderAppend)
   ' // Then rotate
   hStatus = GdipRotateMatrix(matrix, 45, MatrixOrderAppend)

   ' // Retrieve matrix elements
   DIM elements(0 TO 5) AS SINGLE
   hStatus = GdipGetMatrixElements(matrix, @elements(0))

   ' // Create font and brush
   DIM fontFamily AS GpFontFamily PTR
   DIM font AS GpFont PTR
   DIM brush AS GpSolidFill PTR
   GdipCreateFontFamilyFromName("Arial", NULL, @fontFamily)
   GdipCreateFont(fontFamily, AfxGdipPointsToPixels(12, TRUE), FontStyleRegular, UnitPixel, @font)
   GdipCreateSolidFill(ARGB_BLACK, @brush)

   ' // Display matrix values
   DIM text AS STRING
   text = "Matrix Elements:" & !"\n"
   text &= "m11 = " & STR(elements(0)) & !"\n"
   text &= "m12 = " & STR(elements(1)) & !"\n"
   text &= "m21 = " & STR(elements(2)) & !"\n"
   text &= "m22 = " & STR(elements(3)) & !"\n"
   text &= "dx  = " & STR(elements(4)) & !"\n"
   text &= "dy  = " & STR(elements(5))
   DIM layout AS GpRectF = (10.0, 10.0, 300.0, 200.0)
   GdipDrawString(graphics, text, LEN(text), font, @layout, NULL, brush)

   ' // Cleanup
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipInvertMatrix

If the matrix is invertible, this function replaces its elements with the elements of its inverse.

FUNCTION GdipInvertMatrix (BYVAL matrix AS GpMatrix PTR) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.

Example

' ========================================================================================
' The following example passes the address of a Matrix object to the SetTransform method
' of a Graphics object and then draws a rectangle. The rectangle is translated 30 units
' right and 20 units down by the world transformation of the Graphics object. The code
' calls the Matrix.Invert method of the Matrix object and sets the world transformation
' of the Graphics object to the inverted matrix. The code draws a second rectangle that is
' translated 30 units left and 20 units up.
' ========================================================================================
SUB Example_MatrixInvert (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96

   ' // Create a matrix
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix2(1, 0, 0, 1, 30 *rxRatio, 20 * ryRatio, @matrix)

   ' // Create a pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLUE, 1 * rxRatio, UnitPixel, @pen)

   hStatus = GdipSetWorldTransform(graphics, matrix)
   hStatus = GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawRectangle(graphics, pen, 0, 0, 200, 100)

   hStatus = GdipInvertMatrix(matrix)
   hStatus = GdipSetWorldTransform(graphics, matrix)
   hStatus = GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawRectangle(graphics, pen, 0, 0, 200, 100)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipIsMatrixEqual

Determines whether the elements of a matrix are equal to the elements of another matrix.

FUNCTION GdipIsMatrixEqual (BYVAL matrix AS CONST GpMatrix PTR, _
  BYVAL matrix2 AS CONST GpMatrix PTR, BYVAL result AS BOOL PTR) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
matrix2 [in] Pointer to a Matrix object that is compared with another Matrix object.
result [out] Pointer to a variable that receives a boolean value indicating whether the elements of the two matrices are the same (TRUE) or not (FALSE).

Example

'#CONSOLE ON
#define _WIN32_WINNT &h0602
#INCLUDE ONCE "AfxNova/AfxGdiPlus.inc"

' ========================================================================================
' Determines whether the elements of a matrix are equal to the elements of another matrix.
' ========================================================================================

DIM hStatus AS LONG

' // Initialize GDI+
DIM token AS ULONG_PTR = AfxGdipInit

' // Create the matrices
DIM matrix AS GpMatrix PTR
hStatus = GdipCreateMatrix2(1, 2, 1, 1, 2, 2, @matrix)

DIM matrix2 AS GpMatrix PTR
hStatus = GdipCreateMatrix2(1, 2, 1, 1, 2, 2, @matrix2)

DIM result AS BOOL
hStatus = GdipIsMatrixEqual(matrix, matrix2, @result)
IF result THEN PRINT "They are the same"  ELSE PRINT "They are the different"

' // Shutdown GDI+
AfxGdipShutdown token

PRINT
PRINT "Press any key"
SLEEP

GdipIsMatrixIdentity

Determines whether a matrix is the identity matrix.

FUNCTION GdipIsMatrixIdentity (BYVAL matrix AS CONST GpMatrix PTR, BYVAL result AS BOOL PTR) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
result [out] Pointer to a variable that receives a boolean value indicating whether a matrix is the identity matrix (TRUE) or not (FALSE).

Example

'#CONSOLE ON
#define _WIN32_WINNT &h0602
#INCLUDE ONCE "AfxNova/AfxGdiPlus.inc"

' ========================================================================================
' Determines whether a matrix is the identity matrix.
' ========================================================================================

DIM hStatus AS LONG

' // Initialize GDI+
DIM token AS ULONG_PTR = AfxGdipInit

' // Create the matrix
DIM matrix AS GpMatrix PTR
hStatus = GdipCreateMatrix2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, @matrix)

DIM result AS BOOL
hStatus = GdipIsMatrixIdentity(matrix, @result)
IF result THEN PRINT "The matrix is the identity matrix"  ELSE PRINT "The matrix is not the identity matrix"

' // Cleanup
IF matrix THEN GdipDeleteMatrix(matrix)

' // Shutdown GDI+
AfxGdipShutdown token

PRINT
PRINT "Press any key"
SLEEP

GdipIsMatrixInvertible

Determines whether a matrix is invertible.

FUNCTION GdipIsMatrixInvertible (BYVAL matrix AS CONST GpMatrix PTR, BYVAL result AS BOOL PTR) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
result [out] Pointer to a variable that receives a boolean value indicating whether a matrix is invertible (TRUE) or not (FALSE).

Example

'#CONSOLE ON
#define _WIN32_WINNT &h0602
#INCLUDE ONCE "AfxNova/AfxGdiPlus.inc"

' ========================================================================================
' Determines whether a matrix is invertible.
' ========================================================================================

DIM hStatus AS LONG

' // Initialize GDI+
DIM token AS ULONG_PTR = AfxGdipInit

' // Create the matrix
DIM matrix AS GpMatrix PTR
hStatus = GdipCreateMatrix2(3.0, 0.0, 0.0, 2.0, 20.0, 10.0, @matrix)

DIM result AS BOOL
hStatus = GdipIsMatrixInvertible(matrix, @result)
IF result THEN PRINT "The matrix is invertible"  ELSE PRINT "The matrix is not invertible"

' // Cleanup
IF matrix THEN GdipDeleteMatrix(matrix)

' // Shutdown GDI+
AfxGdipShutdown token

PRINT
PRINT "Press any key"
SLEEP

GdipMultiplyMatrix

Updates a matrix with the product of itself and another matrix.

FUNCTION GdipMultiplyMatrix (BYVAL matrix AS GpMatrix PTR, _
   BYVAL matrix2 AS GpMatrix PTR, BYVAL order AS GpMatrixOrder) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
matrix2 [in] Pointer to a matrix that will be multiplied by a matrix.
order [in] Element of the MatrixOrder enumeration that specifies the order of the multiplication. MatrixOrderPrepend specifies that the passed matrix is on the left, and MatrixOrderAppend specifies that the passed matrix is on the right. The default value is MatrixOrderPrepend.

Example

' ========================================================================================
' The following example creates two Matrix objects: matrix1 and matrix2. The call to the
' Matrix.Multiply method updates matrix1 with the product ( matrix1)( matrix2). At that
' point, matrix1 represents a composite transformation: first scale, then translate. The
' code uses matrix1 to set the world transformation of a Graphics object and then draws a
' rectangle that is transformed according to that world transformation.
' ========================================================================================
SUB Example_MultiplyMatrix (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96

   ' // Create a matrix for horizontal scaling
   DIM matrix1 AS GpMatrix PTR
   hStatus = GdipCreateMatrix2(3, 0, 0, 1, 0, 0, @matrix1)

   ' // Translation
   DIM matrix2 AS GpMatrix PTR
   hStatus = GdipCreateMatrix2(1, 0, 0, 1, 20 * rxRatio, 40 * ryRatio, @matrix2)

   ' // Create a pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLUE, 1 * rxRatio, UnitPixel, @pen)

   hStatus = GdipMultiplyMatrix(matrix1, matrix2, MatrixOrderAppend)
   hStatus = GdipSetWorldTransform(graphics, matrix1)
   hStatus = GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawRectangle(graphics, pen, 0, 0, 100, 100)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix1 THEN GdipDeleteMatrix(matrix1)
   IF matrix2 THEN GdipDeleteMatrix(matrix2)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipRotateMatrix

Updates a matrix with the product of itself and a rotation matrix.

FUNCTION GdipRotateMatrix (BYVAL matrix AS GpMatrix PTR, BYVAL angle AS REAL, _
   BYVAL order AS GpMatrixOrder) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
angle [in] Simple precision value that specifies the angle of rotation in degrees. Positive values specify clockwise rotation.
order [in] Element of the MatrixOrder enumeration that specifies the order of the multiplication. MatrixOrderPrepend specifies that the rotation matrix is on the left, and MatrixOrderAppend specifies that the rotation matrix is on the right. The default value is MatrixOrderPrepend.

Example

' ========================================================================================
' The following example creates a Matrix object and calls the GdipTranslateMatrix function
' to set the elements of that matrix to a translation. Then the code calls the GdipRotateMatrix
' function to update the matrix with the product of itself and a rotation matrix. At that
' point, the matrix represents a composite transformation: first translate, then rotate.
' The code uses the matrix to set the world transformation of a Graphics object and then
' draws an ellipse that is transformed according to the composite transformation.
' ========================================================================================
SUB Example_RotateMatrix (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96

   ' // Create a pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLUE, 1 * rxRatio, UnitPixel, @pen)

   ' Create identity matrix
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix(@matrix)

   ' // First a translation
   hStatus = GdipTranslateMatrix(matrix, 40 * rxRatio, 0, MatrixOrderAppend)
   ' Rotate 30 degrees clockwise
   hStatus = GdipRotateMatrix(matrix, 30, MatrixOrderAppend)

   ' // Apply matrix to graphics
   hStatus = GdipSetWorldTransform(graphics, matrix)

   ' // Draw rotated rectangle
   GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawEllipse(graphics, pen, 0, 0, 100, 50)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipScaleMatrix

Updates a matrix with the product of itself and a scaling matrix.

FUNCTION GdipScaleMatrix (BYVAL matrix AS GpMatrix PTR, BYVAL scaleX AS REAL, _
   BYVAL scaleY AS REAL, BYVAL order AS GpMatrixOrder) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
scaleX [in] Simple precision value that specifies the horizontal scale factor.
scaleY [in] Simple precision value that specifies the vertical scale factor.
order [in] Element of the MatrixOrder enumeration that specifies the order of the multiplication. MatrixOrderPrepend specifies that the scaling matrix is on the left, and MatrixOrderAppend specifies that the scaling matrix is on the right. The default value is MatrixOrderPrepend.

Example

' ========================================================================================
' The following example creates a Matrix object and calls the Matrix.Rotate method to set
' the elements of that matrix to a rotation. Then the code calls the Matrix.Scale method
' to update the matrix with the product of itself and a scaling matrix. At that point, the
' matrix represents a composite transformation: first rotate, then scale. The code uses
' the matrix to set the world transformation of a Graphics object and then draws an ellipse
' that is transformed according to the composite transformation.
' ========================================================================================
SUB Example_ScaleMatrix (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96

   ' // Create identity matrix
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix(@matrix)

   ' // Rotate 30 degrees clockwise
   hStatus = GdipRotateMatrix(matrix, 30, MatrixOrderAppend)

   ' // Apply horizontal and vertical scaling
   hStatus = GdipScaleMatrix(matrix, 3.0, 2.0, MatrixOrderAppend)

   ' // Apply matrix to graphics
   hStatus = GdipSetWorldTransform(graphics, matrix)

   ' // Create pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLUE, 2 * rxRatio, UnitPixel, @pen)

   ' // Draw scaled ellipse
   GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawEllipse(graphics, pen, 0, 0, 80, 40)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

Example

' ========================================================================================
' Applies a scaling transformation to a matrix by multiplying it with a scaling matrix.
' This adjusts the size of graphics or coordinates along the X and Y axes.
' ========================================================================================
SUB Example_ScaleMatrix (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96

   ' // Create identity matrix
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix(@matrix)

   ' // Apply horizontal and vertical scaling
   hStatus = GdipScaleMatrix(matrix, 2.0, 1.5, MatrixOrderAppend)

   ' // Apply matrix to graphics
   hStatus = GdipSetWorldTransform(graphics, matrix)

   ' // Create pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLACK, 2 * rxRatio, UnitPixel, @pen)

   ' // Draw scaled rectangle
   GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawRectangle(graphics, pen, 50, 50, 100, 60)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipSetMatrixElements

Sets the elements of the matrix.

FUNCTION GdipSetMatrixElements (BYVAL matrix AS GpMatrix PTR, BYVAL m11 AS REAL, BYVAL m12 AS REAL, _
   BYVAL m21 AS REAL, BYVAL m22 AS REAL, BYVAL dx AS REAL, BYVAL dy AS REAL) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
m11 [in] Simple precision value that specifies the element in the first row, first column.
m12 [in] Simple precision value that specifies the element in the first row, second column.
m21 [in] Simple precision value that specifies the element in the second row, first column.
m22 [in] Simple precision value that specifies the element in the second row, second column.
dx [in] Simple precision value that specifies the element in the third row, first column.
dy [in] Simple precision valuethat specifies the element in the third row, second column.

Example

' ========================================================================================
' The following example calls the GdipSetMatrixElements function. The code uses the matrix
' to set the world transformation of a Graphics object and then draws a rectangle that is
' transformed by that world transformation.
' ========================================================================================
SUB Example_SetMatrixElements (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   DIM ryRatio AS SINGLE = dpiY / 96

   ' // Create identity matrix
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix(@matrix)
   hStatus = GdipSetMatrixElements(matrix, 1, 0, 0, 1, 30 * rxRatio, 50 *ryRatio)

   ' // Apply matrix to graphics
   hStatus = GdipSetWorldTransform(graphics, matrix)

   ' // Scale graphics according the dpi ratios
   hStatus = GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)

   ' // Create a pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLUE, 2 * rxRatio, UnitPixel, @pen)

   ' // Draw a rectangle
   hStatus = GdipDrawRectangle(graphics, pen, 0, 0, 80, 40)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipShearMatrix

Updates a matrix with the product of itself and a shearing matrix.

FUNCTION GdipShearMatrix (BYVAL matrix AS GpMatrix PTR, BYVAL shearX AS REAL, _
   BYVAL shearY AS REAL, BYVAL order AS GpMatrixOrder) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
shearX [in] Simple precision value that specifies the horizontal shear factor.
shearY [in] Simple precision value that specifies the vertical shear factor.
order [in] Element of the MatrixOrder enumeration that specifies the order of the multiplication. MatrixOrderPrepend specifies that the shearing matrix is on the left, and MatrixOrderAppend specifies that the shearing matrix is on the right. The default value is MatrixOrderPrepend.

Example

' ========================================================================================
' The following example creates a Matrix object and calls the GdipScaleMatrix function to set
' the elements of that matrix to a scaling transformation. Then the code calls the GdipShearMatrix
' function to update the matrix with the product of itself and a shearing matrix. At that point,
' the matrix represents a composite transformation: first scale, then shear. The code uses
' the matrix to set the world transformation of a Graphics object and then draws a rectangle
' that is transformed according to the composite transformation.
' In the call to GdipShearMatrix, the shearX parameter is 3 and the shearY parameter is 0.
' That particular shearing transformation slides the bottom edge of the rectangle to the
' right. The distance that the bottom edge slides is shearX multiplied by the height of
' the rectangle after it is stretched by the scaling transformation.
' ========================================================================================
SUB Example_ShearMatrix (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96

   ' // Create identity matrix
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix(@matrix)

   ' // First a scaling
   hStatus = GdipScaleMatrix(matrix, 2.0, 2.0, MatrixOrderAppend)

   ' // Then a shear
   hStatus = GdipShearMatrix(matrix, 3.0, 0.0, MatrixOrderAppend)

   ' // Apply matrix to graphics
   hStatus = GdipSetWorldTransform(graphics, matrix)

   ' // Create pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLACK, 2 * rxRatio, UnitPixel, @pen)

   ' // Draw scaled rectangle
   GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)
   hStatus = GdipDrawRectangle(graphics, pen, 0, 0, 100, 50)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipTransformMatrixPoints

Multiplies each point in an array by a matrix. Each point is treated as a row matrix. The multiplication is performed with the row matrix on the left and a matrix on the right.

FUNCTION GdipTransformMatrixPoints (BYVAL matrix AS GpMatrix PTR, _
   BYVAL pts AS GpPointF PTR, BYVAL count AS INT_) AS GpStatus
FUNCTION GdipTransformMatrixPointsI (BYVAL matrix AS GpMatrix PTR, _
   BYVAL pts AS GpPoint PTR, BYVAL count AS INT_) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
matrix [in, out] Pointer to an array of GpPointF structures that, on input, contains the points to be transformed and, on output, receives the transformed points. Each point in the array is transformed (multiplied by a matrix) and updated with the result of the transformation.
count [in] Long integer value that specifies the number of points to be transformed. The default value is 1.

Example

' ========================================================================================
' The following example creates an array of five points and then transforms those points
' by calling the GdipTransformMatrixPoints function. The code passes the array of points
' to the GdipDrawCurve function before the transformation and again after the transformation.
' ========================================================================================
SUB Example_TransformMatrixPoints (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96
   hStatus = GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)

   ' // Create identity matrix
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix2(1, 0, 0, 2, 0, 0, @matrix)

   ' // Array of points
   DIM rgPoints(0 TO 4) AS GpPointF = {(50, 100), (100, 50), _
       (160, 125), (200, 100), (250, 150)}

   ' // Create pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLUE, 1 * rxRatio, UnitPixel, @pen)

   ' // Draw the curve
   hStatus = GdipDrawCurve(graphics, pen, @rgPoints(0), 5)
   ' // Transform the points
   hStatus = GdipTransformMatrixPoints(matrix, @rgPoints(0), 5)
   ' // Draw the curve after the transformation
   hStatus = GdipDrawCurve(graphics, pen, @rgPoints(0), 5)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipTranslateMatrix

Updates a matrix with the product of itself and a translation matrix.

FUNCTION GdipTranslateMatrix (BYVAL matrix AS GpMatrix PTR, BYVAL offsetX AS REAL, _
   BYVAL offsetY AS REAL, BYVAL order AS GpMatrixOrder) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
offsetX [in] Single precision value that specifies the horizontal component of the translation.
offsetY [in] Single precision value that specifies the vertical component of the translation.
order [in] Element of the MatrixOrder enumeration that specifies the order of the multiplication. MatrixOrderPrepend specifies that the translation matrix is on the left, and MatrixOrderAppend specifies that the translation matrix is on the right. The default value is MatrixOrderPrepend.

Example

' ========================================================================================
' The following example creates a Matrix object and calls the GdipRotateMatrix function to
' set the elements of that matrix to a rotation. Then the code calls the GdipTranslateMatrix
' function to update the matrix with the product of itself and a translation matrix. At that
' point, the matrix represents a composite transformation: first rotate, then translate.
' The code uses the matrix to set the world transformation of a Graphics object and then
' draws an ellipse that is transformed according to the composite transformation.
' ========================================================================================
SUB Example_TranslateMatrix (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96

   ' // Create identity matrix
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix(@matrix)

   ' // First a rotation
   hStatus = GdipRotateMatrix(matrix, 30, MatrixOrderAppend)
   ' // Then a translation
   hStatus = GdipTranslateMatrix(matrix, 150 * rxRatio, 100 * ryRatio, MatrixOrderAppend)

   ' // Apply matrix to graphics
   hStatus = GdipSetWorldTransform(graphics, matrix)

   ' // Create pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLUE, 1 * rxRatio, UnitPixel, @pen)

   ' // Scale graphics according the dpi ratios
   hStatus = GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)

   ' // Draw a tramsformed ellipse. The composite transformation
   ' // is rotate 30 degrees, then translate 150 right and 100 down.
   hstatus = GdipDrawEllipse(graphics, pen, -40, -20, 80, 40)

   ' // Draw rotated axes with the origin at the center of the ellipse.
   hStatus = GdipDrawLine(graphics, pen, -50, 0, 50, 0)
   hStatus = GdipDrawLine(graphics, pen, 0, -50, 0, 50)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================

GdipVectorTransformMatrixPoints

Multiplies each vector in an array by a matrix. The translation elements of a matrix (third row) are ignored. Each vector is treated as a row matrix. The multiplication is performed with the row matrix on the left and a matrix on the right.

FUNCTION GdipVectorTransformMatrixPoints (BYVAL matrix AS GpMatrix PTR, _
   BYVAL pts AS GpPointF PTR, BYVAL count AS INT_) AS GpStatus
FUNCTION GdipVectorTransformMatrixPointsI (BYVAL matrix AS GpMatrix PTR, _
   BYVAL pts AS GpPoint PTR, BYVAL count AS INT_) AS GpStatus
Parameter Description
matrix [in] Pointer to the Matrix object.
pts [in, out] Pointer to an array of GpPointF objects that, on input, contains the vectors to be transformed and, on output, receives the transformed vectors. Each vector in the array is transformed (multiplied by a matrix) and updated with the result of the transformation.
count [in] Long integer value that specifies the number of points to be transformed. The default value is 1.

Example

' ========================================================================================
' The following example creates a vector and a point. The tip of the vector and the point
' are at the same location: (100, 50). The code creates a Matrix object and initializes its
' elements so that it represents a clockwise rotation followed by a translation 100 units
' to the right. The code calls the GdipTransformMatrixPoints functioon of the matrix
' to transform the point and calls the GdipVectorTransformMatrixPoints function to transform
' the vector. The entire transformation (rotation followed by translation) is performed on
' the point, but only the rotation part of the transformation is performed on the vector.
' The elements of the matrix that represent translation are ignored by the
' GdipVectorTransformMatrixPoints function
' ========================================================================================
SUB Example_VectorTransformMatrixPoints (BYVAL hdc AS HDC)

   DIM hStatus AS LONG

   ' // Create a graphics object from the device context
   DIM graphics AS GpGraphics PTR
   hStatus = GdipCreateFromHDC(hdc, @graphics)

   ' // Get the DPI scaling ratios
   DIM dpiX AS SINGLE
   hStatus = GdipGetDpiX(graphics, @dpiX)
   DIM rxRatio AS SINGLE = dpiX / 96
   DIM dpiY AS SINGLE
   hStatus = GdipGetDpiY(graphics, @dpiY)
   Dim ryRatio AS SINGLE = dpiY / 96
   hStatus = GdipScaleWorldTransform(graphics, rxRatio, ryRatio, MatrixOrderPrepend)

   ' // Create pen
   DIM pen AS GpPen PTR
   hStatus = GdipCreatePen1(ARGB_BLUE, 2 * rxRatio, UnitPixel, @pen)
   hStatus = GdipSetPenEndCap(pen, LineCapArrowAnchor)
   
   ' // Create a solid brush
   DIM brush AS GpSolidFill PTR
   hStatus = GdipCreateSolidFill(ARGB_BLUE, @brush)
   
   ' // A point and a vector, same representation but different behavior
   DIM pt AS GpPointF = (100, 50)
   DIM vector AS GpPointF = (100, 50)

   ' // Draw the original point and vector in blue
   hStatus = GdipFillEllipse(graphics, brush, pt.x - 5.0, pt.y - 5.0, 10.0, 10.0)
   hStatus = GdipDrawLine(graphics, pen, 0, 0, vector.x, vector.y)

   ' // Transform
   DIM matrix AS GpMatrix PTR
   hStatus = GdipCreateMatrix2(0.8, 0.6, -0.6, 0.8, 100.0, 0.0,@matrix)
   hStatus = GdipTransformMatrixPoints(matrix, @pt, 1)
   hStatus = GdipVectorTransformMatrixPoints(matrix, @vector, 1)

   ' // Draw the transformed point and vector in red.
   hStatus = GdipSetPenColor(pen, ARGB_RED)
   hStatus = GdipSetSolidFillColor(brush, ARGB_RED)
   hStatus = GdipFillEllipse(graphics, brush, pt.X - 5.0, pt.Y - 5.0, 10.0, 10.0)
   hStatus = GdipDrawLine(graphics, pen, 0, 0, vector.x, vector.y)

   ' // Cleanup
   IF pen THEN GdipDeletePen(pen)
   IF brush THEN GdipDeleteBrush(brush)
   IF matrix THEN GdipDeleteMatrix(matrix)
   IF graphics THEN GdipDeleteGraphics(graphics)

END SUB
' ========================================================================================